home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dd / console.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  34KB  |  1,357 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include    "defs.h"
  7. #include    "dbug_protos.h"
  8. #include    <ctype.h>
  9. #include    "dd_rev.h"
  10.  
  11.  
  12. // ************************************************************************
  13.  
  14. Prototype void        InitConsole(void);
  15. Prototype LONG        ScrMainBodyRange(void *ptop, void *pbot);
  16. Prototype LONG        ScrColumns(WORD overhead, WORD itemWidth, WORD limit);
  17. Prototype void        ScrFlush(void);
  18. Prototype void        ScrPutNewline(void);
  19. Prototype void        ScrPutChar(UBYTE c);
  20. Prototype void        ScrWrite(char *s, ULONG len);
  21. Prototype void        ScrPuts(char *s);
  22. Prototype void        ScrPutsCtl(char *s);
  23. Local unsigned int    _swrite(char *buf, size_t n1, size_t n2, const char **sst);
  24. Prototype WORD        ScrPrintf(const char *fmt, ...);
  25. Prototype void        ScrStatus(const char *fmt, ...);
  26. Local void        QueueRead(void);
  27. Local void        HandleConsoleInput(struct DBugDisp *disp, WORD c);
  28. Prototype void        ScrHome(void);
  29. Prototype void        ScrCursoff(void);
  30. Prototype void        ScrCurson(void);
  31. Prototype void        ScrClr(void);
  32. Prototype void        ScrRowCol(UWORD row, UWORD col);
  33. Prototype void        ScrEOL(void);
  34. Prototype void        ScrHighlight(void);
  35. Prototype void        ScrDull(void);
  36. Prototype void        ScrPlain(void);
  37. Prototype void        ScrInverse(void);
  38. Prototype void        ScrItalics(void);
  39. Prototype void        ScrUnderline(void);
  40. Prototype void        ScrScrollup(void);
  41. Prototype void        ScrScrolldown(void);
  42. __autoexit Local void    ScrClose(void);
  43. Prototype DBugDisp     *ScrOpen(BOOL first, BOOL refresh, char *pubname);
  44. Prototype void        ScrScrollClr(void);
  45. Prototype void        GetWindowSize(void);
  46. Prototype void        EnterDebugger(void);
  47.  
  48. Prototype void        CloseDisplay(struct DBugDisp *);
  49. Prototype void        RequestCloseDisplay(struct DBugDisp *, int );
  50. Prototype BOOL        CheckCloseDisplay(void);
  51. Prototype void        ProcessDataAtCoord(DBugDisp *disp, WORD x, WORD y);
  52. Prototype void         SetTitle(char *title, DBugDisp *disp);
  53.  
  54. Prototype void         draw_fkey_boxes(void);
  55. Prototype void        drawdoublebox(void);
  56. Local       void         drawbox(int xcol,int yrow, int xlen, int ylen);
  57. Local     void        do_putc(DBugDisp *disp, UBYTE c);
  58.  
  59. // ************************************************************************
  60.  
  61. Prototype struct DBugDisp  *CurDisplay;
  62. Prototype LIST    DisplayList;
  63.  
  64. // ************************************************************************
  65.  
  66. #define CONIDCMP    NULL
  67. #define IFLAGS         IDCMP_NEWSIZE|IDCMP_MOUSEBUTTONS|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_MENUPICK|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW
  68. #define IFLAGS_FULL     IFLAGS|IDCMP_MOUSEMOVE|IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_INTUITICKS
  69.  
  70. extern struct Menu      *DebugMenu;
  71.  
  72. extern struct Gadget ColorGadget;
  73. extern struct Gadget DownGadget;
  74. extern struct Gadget UpGadget;
  75. extern struct Image ColorPropImage;
  76. extern struct PropInfo ColorPropInfo;
  77.  
  78. DBugDisp    *CurDisplay;    //    currently active display/window
  79. LIST        DisplayList;    //    list of open windows
  80. MPORT        DBugPort;        //    Master debug port for all console IO
  81. WORD        CheckClose;
  82. char        ValidClipChar[256];
  83. static int  count = 0;    
  84. #if 0
  85. static int  ignoreclick = 0;
  86. #endif
  87. static int  PageFlag = 0;
  88. static int  Ticked = 0;
  89.  
  90. USHORT    oldrow = 0xFFFF;    /* last mouse click position */
  91. USHORT  oldcol = 0xFFFF;    
  92.  
  93. static ULONG seconds=0;
  94. static ULONG micros=0;
  95.  
  96. // ************************************************************************
  97.  
  98. void    InitConsole(void) {
  99.  
  100.     WORD i;
  101.  
  102.  
  103.     NewList(&DisplayList);
  104.  
  105.     DBugPort.mp_Flags  = PA_SIGNAL;
  106.     DBugPort.mp_SigBit = SIGB_SINGLE;
  107.     DBugPort.mp_SigTask = FindTask(NULL);
  108.     NewList(&DBugPort.mp_MsgList);
  109.  
  110.     SetSignal(0L,SIGF_SINGLE);
  111.  
  112.     for (i = '0'; i <= '9'; ++i)ValidClipChar[i] = 1;
  113.     for (i = 'a'; i <= 'z'; ++i)ValidClipChar[i] = 1;
  114.     for (i = 'A'; i <= 'Z'; ++i)ValidClipChar[i] = 1;
  115.     ValidClipChar['+'] = 1;
  116.     ValidClipChar['_'] = 1;
  117.     ValidClipChar['@'] = 1;
  118.     ValidClipChar['$'] = 1;
  119.     ValidClipChar['.'] = 1;
  120.  
  121.     ValidClipChar['-'] = 1;
  122. }
  123.  
  124.  
  125.  
  126. // ************************************************************************
  127.  
  128. void    ScrFlush(void) {
  129.     DBugDisp *disp;
  130.  
  131.     if ((disp = CurDisplay) && disp->ds_COutIndex) {
  132.         disp->ds_CWriteReq.io_Command = CMD_WRITE;
  133.         disp->ds_CWriteReq.io_Data = (APTR)disp->ds_COutBuf;
  134.         disp->ds_CWriteReq.io_Length = disp->ds_COutIndex;
  135.         DoIO((IOREQ *)&disp->ds_CWriteReq);
  136.         disp->ds_COutIndex = 0;
  137.     }
  138. }
  139.  
  140. void    ScrPutChar(UBYTE c) {
  141.     DBugDisp *disp;
  142.  
  143.     if (disp = CurDisplay) {
  144.         disp->ds_COutBuf[disp->ds_COutIndex++] = c;
  145.         if (disp->ds_COutIndex == sizeof(disp->ds_COutBuf))ScrFlush();
  146.         if (c == '\t') {
  147.             int i = 8 - (disp->ds_ScrColNo & 7);
  148.             while(i--)do_putc(disp,' ');
  149.         }
  150.         else do_putc(disp,c);
  151.     }
  152. }
  153.  
  154. void do_putc(DBugDisp *disp,UBYTE c)
  155. {
  156.     if (disp->ds_ScrColNo < disp->ds_ScrCols && disp->ds_ScrRowNo < disp->ds_ScrRows && disp->ds_ScrAry)
  157.         disp->ds_ScrAry[disp->ds_ScrColNo++ + disp->ds_ScrCols * disp->ds_ScrRowNo] = c;
  158. }
  159.  
  160.  
  161. void    ScrPutCharCtl(UBYTE c) {
  162.     DBugDisp *disp;
  163.  
  164.     if (disp = CurDisplay) {
  165.         disp->ds_COutBuf[disp->ds_COutIndex++] = c;
  166.         if (disp->ds_COutIndex == sizeof(disp->ds_COutBuf))
  167.             ScrFlush();
  168.     }
  169. }
  170.  
  171.  
  172. void    ScrWrite(char *s, ULONG len) {
  173.  
  174.     while (len > 0) {
  175.         ScrPutChar(*s++);
  176.         --len;
  177.     }
  178. }
  179.  
  180. void    ScrPuts(char *s) {
  181.  
  182.     while (*s)ScrPutChar(*s++);
  183. }
  184.  
  185. void    ScrPutsCtl(char *s) {
  186.  
  187.     while (*s)ScrPutCharCtl(*s++);
  188.  
  189. }
  190.  
  191. // ************************************************************************
  192.  
  193. Local unsigned int _swrite(char *buf, size_t n1, size_t n2, const char **sst) {
  194.     size_t n;
  195.  
  196.     if (n1 == 1)
  197.         n = n2;
  198.     else if (n2 == 1)
  199.         n = n1;
  200.         else
  201.         n = n1 * n2;
  202.  
  203.     _slow_bcopy(buf, *sst, n);
  204.     *sst += n;
  205.     return(n2);
  206. }
  207.  
  208. WORD    ScrPrintf(const char *fmt, ...) {
  209.     char        buf[128];
  210.     char        *ptr = &buf[0];
  211.     va_list     va;
  212.     WORD        n;
  213.  
  214.     va_start(va, fmt);
  215.     n = (WORD)_pfmt(fmt, va, _swrite, &ptr);
  216.     *ptr = 0;
  217.     ScrPuts(buf);
  218.  
  219.     va_end(va);
  220.     n = strlen(buf);
  221.     return n;
  222. }
  223.  
  224. void    ScrStatus(const char *fmt, ...) {
  225.     static char    buf[128];
  226.     char        *ptr = &buf[0];
  227.     va_list     va;
  228.  
  229.     ScrPlain();
  230.     ScrDull();
  231.  
  232.     va_start(va, fmt);
  233.     _pfmt(fmt, va, _swrite, &ptr);
  234.     *ptr = 0;
  235.  
  236.     ScrRowCol(CurDisplay->ds_ScrRows-2, 1);
  237.  
  238.     ScrPuts(" < Status: ");
  239.  
  240.     ScrInverse();
  241.     ScrPuts(buf);
  242.     ScrPlain(); 
  243.     ScrDull();
  244.  
  245.     ScrPuts(" > ");
  246. //    ScrPlain();
  247.  
  248.     CurDisplay->ds_PromptStart = strlen(buf)+14;
  249.     RefreshPrompt(TRUE);
  250.     strcpy(RexxReplyString,buf);    // for Arexx users
  251.     va_end(va);
  252. }
  253.  
  254. // ************************************************************************
  255.  
  256. Local void    QueueRead(void) {
  257.     DBugDisp *disp;
  258.  
  259.     if (disp = CurDisplay) {
  260.         if (disp->ds_CReadIP == 0) {
  261.             disp->ds_CReadReq.io_Command = CMD_READ;
  262.             disp->ds_CReadReq.io_Data = (APTR)&disp->ds_CInChar;
  263.             disp->ds_CReadReq.io_Length = 1;
  264.             SendIO((IOREQ *)&disp->ds_CReadReq);
  265.             disp->ds_CReadIP = 1;
  266.         }
  267.     }
  268. }
  269.  
  270.  
  271. // ************************************************************************
  272.  
  273. void    ScrPutNewline(void) {
  274.     DBugDisp *disp;
  275.  
  276.     ScrPutCharCtl('\n');
  277.  
  278.     if (disp = CurDisplay) {
  279.         disp->ds_ScrColNo = 0;
  280.         ++disp->ds_ScrRowNo;
  281.     }
  282. }
  283.  
  284. void    ScrHome(void) {
  285.     DBugDisp *disp;
  286.  
  287.     ScrPutsCtl("\x9b" "0;0\x48");
  288.     if (disp = CurDisplay) {
  289.         disp->ds_ScrColNo = 0;
  290.         disp->ds_ScrRowNo = 0;
  291.     }
  292. }
  293.  
  294. void    ScrCursoff(void) {
  295.     ScrPutsCtl("\x9b" "0 \x70");
  296. }
  297.  
  298. void    ScrCurson(void) {
  299.     ScrPutsCtl("\x9b" " \x70");
  300.     ScrFlush();
  301. }
  302.  
  303. void    ScrClr(void) {
  304.     DBugDisp *disp;
  305.  
  306.     ScrPutCharCtl(12);
  307.     if (disp = CurDisplay) {
  308.         disp->ds_ScrColNo = 0;
  309.         disp->ds_ScrRowNo = 0;
  310.         if (disp->ds_ScrAry)
  311.             clrmem(disp->ds_ScrAry, disp->ds_ScrRows * disp->ds_ScrCols);
  312.     }
  313. }
  314.  
  315. void    ScrRowCol(UWORD row, UWORD col) {
  316.     DBugDisp *disp;
  317.     char buf[32];
  318.  
  319.     sprintf(buf, "\x9b" "%d;%d\x48", row, col);
  320.     ScrPutsCtl(buf);
  321.  
  322.     if (disp = CurDisplay) {
  323.         disp->ds_ScrColNo = col - 1;
  324.         disp->ds_ScrRowNo = row - 1;
  325.     }
  326. }
  327.  
  328.  
  329. void    ScrEOL(void) {
  330.     DBugDisp *disp;
  331.  
  332.     ScrPutsCtl("\x9b" "\x4b");
  333.     if ((disp = CurDisplay) && disp->ds_ScrAry) {
  334.         if (disp->ds_ScrRowNo < disp->ds_ScrRows && disp->ds_ScrColNo < disp->ds_ScrCols)
  335.             clrmem(disp->ds_ScrAry + disp->ds_ScrRowNo * disp->ds_ScrCols + disp->ds_ScrColNo, disp->ds_ScrCols - disp->ds_ScrColNo);
  336.     }
  337. }
  338.  
  339. void    ScrHighlight(void) {
  340.     if (IntuitionBase->ActiveScreen->BitMap.Depth == 1)
  341.         ScrPutsCtl("\x9b" "7\x6d");
  342.     else ScrPutsCtl("\x9b" "32\x6d");
  343. }
  344.  
  345. void    ScrDull(void) {
  346.     if (IntuitionBase->ActiveScreen->BitMap.Depth == 1)
  347.         ScrPutsCtl("\x9b" "3\x6d");
  348.     else    ScrPutsCtl("\x9b" "33\x6d");
  349. }
  350.  
  351. void    ScrPlain(void) {
  352.     ScrPutsCtl("\x9b" "0\x6d");
  353. }
  354.  
  355. void    ScrInverse(void) {
  356.     ScrPutsCtl("\x9b" "7\x6d");
  357. }
  358.  
  359. void    ScrItalics(void) {
  360.     ScrPutsCtl("\x9b" "3\x6d");
  361. }
  362.  
  363. void    ScrUnderline(void) {
  364.     ScrPutsCtl("\x9b" "4\x6d");
  365. }
  366.  
  367. // scroll only scrollable window part up one line
  368. // i.e. like a normal line feed
  369.  
  370. void    ScrScrollup(void) {
  371.     DBugDisp *disp;
  372.     WINDOW     *win;
  373.  
  374.     if ((disp = CurDisplay) && (win = disp->ds_Win)) {
  375.         RPORT     *rp = win->RPort;
  376.         UWORD    top = win->BorderTop + disp->ds_ScrTop * rp->TxHeight;
  377.         UWORD    bottom = top + ScrMainBodyRange(NULL, NULL) * rp->TxHeight;
  378.         ULONG    topln;
  379.         ULONG    botln;
  380.  
  381.         ScrollRaster(rp, 0, rp->TxHeight, win->BorderLeft, top, CurDisplay->ds_ScrCols * rp->TxWidth + 3, bottom - 1);
  382.         ScrMainBodyRange(&topln, &botln);
  383.         --topln;
  384.         if (disp->ds_ScrAry && botln < disp->ds_ScrRows) {
  385.             //kprintf("top = %d bot = %d\n", topln, botln);
  386.             movmem(disp->ds_ScrAry + (UWORD)(topln + 1) * disp->ds_ScrCols,
  387.                 disp->ds_ScrAry + (UWORD)topln * disp->ds_ScrCols,
  388.                 (UWORD)(botln - topln - 1) * disp->ds_ScrCols
  389.             );
  390.             clrmem(disp->ds_ScrAry + (UWORD)(botln - 1) * disp->ds_ScrCols, disp->ds_ScrCols);
  391.         }
  392.         ScrRowCol(botln, 1);
  393.     }
  394. }
  395.  
  396. // scroll only scrollable window part down one line
  397.  
  398. void    ScrScrolldown(void) {
  399.     DBugDisp *disp;
  400.     WINDOW     *win;
  401.  
  402.     if ((disp = CurDisplay) && (win = disp->ds_Win)) {
  403.         RPORT     *rp = win->RPort;
  404.         UWORD    top = win->BorderTop + disp->ds_ScrTop * rp->TxHeight;
  405.         UWORD    bottom = top + ScrMainBodyRange(NULL,NULL) * rp->TxHeight;
  406.         ULONG    topln;
  407.         ULONG    botln;
  408.  
  409.         ScrollRaster(rp, 0, -rp->TxHeight, win->BorderLeft, top, CurDisplay->ds_ScrCols * rp->TxWidth + 3, bottom - 1);
  410.         ScrMainBodyRange(&topln, &botln);
  411.         ScrRowCol(topln, 1);
  412.         --topln;
  413.         if (disp->ds_ScrAry && botln < disp->ds_ScrRows) {
  414.             movmem(disp->ds_ScrAry + (UWORD)topln * disp->ds_ScrCols,
  415.                 disp->ds_ScrAry + (UWORD)(topln + 1) * disp->ds_ScrCols,
  416.                 (UWORD)(botln - topln - 1) * disp->ds_ScrCols
  417.             );
  418.             clrmem(disp->ds_ScrAry + (UWORD)topln * disp->ds_ScrCols, disp->ds_ScrCols);
  419.         }
  420.  
  421.     }
  422. }
  423.  
  424. // Clear the Scrollable area of the screen
  425.  
  426. void    ScrScrollClr(void) {
  427.     DBugDisp *disp;
  428.     WINDOW     *win;
  429.  
  430.     if ((disp = CurDisplay) && (win = disp->ds_Win)) {
  431.         RPORT     *rp = win->RPort;
  432.         UWORD    top = win->BorderTop + disp->ds_ScrTop * rp->TxHeight;
  433.         UWORD    bottom = top + ScrMainBodyRange(NULL, NULL) * rp->TxHeight;
  434.         ULONG    topln;
  435.         ULONG    botln;
  436.  
  437.         SetAPen(rp,0);
  438.         RectFill(rp, win->BorderLeft, top, CurDisplay->ds_ScrCols * rp->TxWidth + 3, bottom - 1);
  439.         ScrMainBodyRange(&topln, &botln);
  440.         if (disp->ds_ScrAry && (topln < botln) && (topln < disp->ds_ScrRows)) {
  441.             clrmem(disp->ds_ScrAry + (UWORD)(topln) * disp->ds_ScrCols, 
  442.                 (botln - topln) * disp->ds_ScrCols);
  443.         }
  444.         ScrRowCol(botln, 1);
  445.     }
  446. }
  447.  
  448. //  Return the main body range in console coordinates (row, col start
  449. //  at 1)
  450.  
  451. LONG    ScrMainBodyRange(void *ptop, void *pbot) {
  452.  
  453.     if (ptop) {
  454.         //  top line, scroll area
  455.         *(long *)ptop = CurDisplay->ds_ScrTop + 1;
  456.     }
  457.     if (pbot)
  458.         *(long *)pbot = CurDisplay->ds_ScrRows - 4;    //  bottom line, scroll area
  459.     return (CurDisplay->ds_ScrRows - CurDisplay->ds_ScrTop - 4);      //  # lines in scroll area
  460. }
  461.  
  462. LONG    ScrColumns(WORD overhead, WORD itemWidth, WORD limit) {
  463.     LONG cols = (CurDisplay->ds_ScrCols - overhead) / itemWidth;
  464.     LONG n;
  465.  
  466.     if (cols < 0)
  467.         cols = 0;
  468.     if (cols > limit)        /*  no greater then 16    */
  469.         cols = limit;
  470.  
  471.     for (n = 1; n <= cols; n <<= 1)  /*  power of 2 boundry  */
  472.         ;
  473.     return (n >> 1);
  474. }
  475.  
  476. // ************************************************************************
  477.  
  478. __autoexit Local void    ScrClose(void) {
  479.     DBugDisp *disp;
  480.  
  481.     while ((disp = (DBugDisp *)DisplayList.lh_Head) != (DBugDisp *)&DisplayList.lh_Tail) {
  482.         if(!disp) {
  483.         break;    
  484.         }
  485.         CloseDisplay(disp);
  486.     }
  487.        free_menus();
  488. }
  489.  
  490. BOOL    CheckCloseDisplay(void) {
  491.     DBugDisp    *disp;
  492.     BOOL        retval = TRUE;
  493.     BOOL        flag = TRUE;
  494.  
  495.     CheckClose = FALSE;
  496.  
  497.  
  498.     while(flag) {
  499.     flag = FALSE;
  500.     for (disp = (DBugDisp *)DisplayList.lh_Head; disp->ds_Node.ln_Succ; disp = (DBugDisp *)disp->ds_Node.ln_Succ) {
  501.         if (!disp->ds_DoneFlag) {
  502.         // can't exit, we still have a window open
  503.         retval = FALSE;
  504.         }
  505.         else {
  506.         CloseDisplay(disp);
  507.         flag = TRUE;
  508.         break;    // disp is illegal at the moment, start scan again
  509.         }
  510.     }
  511.     }
  512.     return retval;
  513. }
  514.  
  515.  
  516. void    CloseDisplay(DBugDisp *disp) {
  517.  
  518.     if(!disp)return;
  519.     Remove(&disp->ds_Node);
  520.  
  521.     if (disp->ds_CReadIP) {
  522.         AbortIO((IOREQ *)&disp->ds_CReadReq);
  523.         WaitIO((IOREQ *)&disp->ds_CReadReq);
  524.         disp->ds_CReadIP = 0;
  525.     }
  526.     if (disp->ds_CWriteIP) {
  527.         AbortIO((IOREQ *)&disp->ds_CWriteReq);
  528.         WaitIO((IOREQ *)&disp->ds_CWriteReq);
  529.         disp->ds_CWriteIP = 0;
  530.     }
  531.     if (disp->ds_CReadReq.io_Device) {
  532.         CloseDevice((IOREQ *)&disp->ds_CReadReq);
  533.         disp->ds_CReadReq.io_Device = NULL;
  534.     }
  535.     if (disp->ds_ScrAry) {
  536.         Free(disp->ds_ScrAry);
  537.         disp->ds_ScrAry = NULL;
  538.     }
  539.     if (disp->ds_Win) {
  540.         //  XXX what about IDCMP that is hanging on to our port?
  541.         //  when intuition reclaims the messages the port list
  542.         //  will probably become invalid
  543.  
  544.         RequestCloseDisplay(disp,TRUE);
  545.         ClearMenuStrip(disp->ds_Win);
  546.         CloseWindow(disp->ds_Win);
  547.         disp->ds_Win = NULL;
  548.     }
  549.  
  550.     if(CurDisplay == disp) {
  551.         CurDisplay = NULL;
  552.     }
  553.  
  554.     FreeMem(disp, sizeof(DBugDisp));
  555. }
  556.  
  557. char    version[] = VERSTAG " Copyright 1992, O.I.C., Redistribution and use under DICE-LICENSE.TXT\n";
  558.  
  559.  
  560. static struct ExtNewWindow nw = {
  561.     0,0,        /* window XY origin relative to TopLeft of screen */
  562.     640,200,    /* window width and height */
  563.     0,1,        /* detail and block pens   */
  564.     0,        /* 0 IDCMP  */
  565.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|ACTIVATE,
  566.     NULL,        /* first gadget in gadget list */
  567.     NULL,        /* custom CHECKMARK imagery */
  568.     NULL,        /* window title */
  569.     NULL,        /* custom screen pointer */
  570.     NULL,        /* custom bitmap */
  571.     64,64,        /* minimum width and height */
  572.     -1,-1,        /* maximum width and height */
  573.     WBENCHSCREEN,    /* destination screen type */
  574.     NULL
  575. };
  576.  
  577. DBugDisp *ScrOpen(BOOL first, BOOL refresh, char *pubname) {
  578.     DBugDisp *disp;
  579.     DBugDisp *old = CurDisplay;
  580.     BOOL ok = FALSE;
  581.  
  582.     if (disp = AllocMem(sizeof(DBugDisp), MEMF_PUBLIC|MEMF_CLEAR)) {
  583.         NewList((LIST *)&disp->ds_List);
  584.         nw.LeftEdge = dprefs.left;
  585.         nw.TopEdge = dprefs.top;
  586.         nw.Width = dprefs.width;
  587.         nw.Height = dprefs.height;
  588.  
  589.         if (old) {
  590.             disp->ds_DisplayOffsets = old->ds_DisplayOffsets;
  591.             disp->ds_DisplayMode = old->ds_DisplayMode;
  592.             disp->ds_PreferedMode = old->ds_PreferedMode;
  593.             disp->ds_WindowTop    = old->ds_WindowTop;
  594.             disp->ds_WindowTopLine= old->ds_WindowTopLine;
  595.             disp->ds_WindowBot    = old->ds_WindowBot;
  596.             disp->ds_WindowBotLine= old->ds_WindowBotLine;
  597.         } 
  598.         else {
  599.             // first window, depend on preferences
  600.             disp->ds_DisplayMode = dprefs.DefaultMode;
  601.             disp->ds_PreferedMode = dprefs.DefaultMode;
  602.             disp->ds_DisplayOffsets = dprefs.DefaultOffset;
  603.             disp->ds_LastRefreshMode = DISPLAY_BYTES;
  604.         }
  605.  
  606.         if(pubname && *pubname && (((struct Library *)SysBase)->lib_Version >= 36)) {
  607.             struct Screen *pub_screen;
  608.             struct TagItem wtags[3];
  609.  
  610.             nw.Flags |= WFLG_NW_EXTENDED;
  611.             nw.Extension = wtags;
  612.             wtags[0].ti_Tag = WA_PubScreenName;
  613.             wtags[0].ti_Data = (ULONG)pubname;
  614.             wtags[1].ti_Tag = WA_PubScreenFallBack;
  615.             wtags[1].ti_Data = TRUE;
  616.             wtags[2].ti_Tag = TAG_END;
  617.             wtags[2].ti_Data = 0;
  618.  
  619.                 if(pub_screen = LockPubScreen(pubname)) {
  620.                 disp->ds_Win = OpenWindow((struct NewWindow *)&nw);
  621.                 UnlockPubScreen(pubname,pub_screen);
  622.             }
  623.         }
  624.         else {
  625.             memset(DefaultPubName,0,128);    // clear the name
  626.             nw.Flags &= ~WFLG_NW_EXTENDED;    // clear the ext bit
  627.             disp->ds_Win = OpenWindow((struct NewWindow *)&nw);
  628.         }
  629.  
  630.         if(disp->ds_Win) {
  631.             PageFlag = 0;
  632.             SetTitle(NULL,disp);    // set the window title
  633.             disp->ds_Win->UserPort = &DBugPort;
  634.  
  635.             ModifyIDCMP(disp->ds_Win,IFLAGS);
  636.  
  637.             disp->ds_CReadReq.io_Message.mn_ReplyPort = &DBugPort;
  638.             disp->ds_CReadReq.io_Data = (APTR)disp->ds_Win;
  639.             disp->ds_CReadReq.io_Length = sizeof(WINDOW);
  640.             if (OpenDevice("console.device", 0, (IOREQ *)&disp->ds_CReadReq, 0) == 0) {
  641.                 disp->ds_CWriteReq = disp->ds_CReadReq;
  642.  
  643.                 CurDisplay = disp;
  644.                 QueueRead();
  645.                 ScrPutsCtl("\x9b" "\x3f\x37\x6c");
  646.                 ScrFlush();
  647.                 GetWindowSize();
  648.                 ok = TRUE;
  649.  
  650.                 setscrollbar(0);    // add the scroll bar
  651.                 ModifyIDCMP(disp->ds_Win,IFLAGS_FULL);
  652.  
  653.                 // start the menu subsystem
  654.                 init_default_menus();
  655.                 enable_menus();
  656.  
  657.                 if (refresh)RefreshWindow(-1);
  658.  
  659.                 //  can't set to new display here except
  660.                 //  for initial because we would be
  661.                 //  pulling it out from under the
  662.                 //  command interpreter
  663.  
  664.                 if (first == 0)    CurDisplay = old;
  665.             }
  666.         }
  667.     }
  668.     if (disp) {
  669.         AddTail(&DisplayList, &disp->ds_Node);
  670.     }
  671.     if (ok == FALSE) {
  672.         if (disp)CloseDisplay(disp);
  673.         if (first) {
  674.         exit(25);
  675.         }
  676.     }
  677.     return disp;
  678. }
  679.  
  680. // ************************************************************************
  681.  
  682. void    GetWindowSize(void) {
  683.     DBugDisp *disp;
  684.     WINDOW     *win;
  685.  
  686.     if ((disp = CurDisplay) && (win = disp->ds_Win)) {
  687.         UWORD rows = (win->Height - win->BorderTop - win->BorderBottom) / win->RPort->TxHeight;
  688.         UWORD cols = (win->Width - win->BorderLeft - win->BorderRight) / win->RPort->TxWidth;
  689.         if (rows != disp->ds_ScrRows || cols != disp->ds_ScrCols) {
  690.             disp->ds_ScrRows = rows;
  691.             disp->ds_ScrCols = cols;
  692.             if (disp->ds_ScrAry)
  693.                 Free(disp->ds_ScrAry);
  694.             if (disp->ds_ScrAry = MallocPublic(rows * cols))
  695.                 clrmem(disp->ds_ScrAry, rows * cols);
  696.         }
  697.     }
  698. }
  699.  
  700. // ************************************************************************
  701.  
  702. #if 0
  703.  void DumpCharmap(void) {
  704.     WORD    row;
  705.     WORD    col;
  706.     DBugDisp *disp = CurDisplay;
  707.  
  708.     fhprintf(Output(), "cols = %d rows = %d\n", disp->ds_ScrCols, disp->ds_ScrRows);
  709.     for (row = 0; row < disp->ds_ScrRows; ++row) {
  710.         for (col = 0; col < disp->ds_ScrCols; ++col) {
  711.             BYTE c = disp->ds_ScrAry[row * disp->ds_ScrCols + col];
  712.             if (c)
  713.                 fhprintf(Output(), "%c", c);
  714.             else
  715.                 fhprintf(Output(), ".");
  716.         }
  717.         fhprintf(Output(), "\n");
  718.     }
  719.  }
  720.  
  721. #endif
  722.  
  723. __geta4 void    EnterDebugger(void) {
  724.     struct    MenuItem *item;
  725.  
  726.     if (CurDisplay && CurDisplay->ds_DisplayMode > DISPLAY_MIXED)
  727.     SetDisplayMode(CurDisplay->ds_PreferedMode, 0);
  728.  
  729.     RefreshWindow(-1);
  730.     ScrStatus("Ready");
  731.     RefreshCommand(1);
  732.     ScrCurson();
  733.  
  734.     SetSignal(0L,SIGF_SINGLE);    // always clear the bit
  735.     while (DisplayList.lh_Head != (NODE *)&DisplayList.lh_Tail) {
  736.     ULONG    mask;
  737.     MSG    *msg;
  738.  
  739.     if (CheckClose && CheckCloseDisplay()) {
  740.         break;
  741.     }
  742.  
  743.  
  744. //    mask = Wait( (1<<DBugPort.mp_SigBit) | (1<<RexxPort.mp_SigBit) );
  745.     mask = Wait( (1<<DBugPort.mp_SigBit) | (1<<RexxSigBit) );
  746.     if (mask & (1<<DBugPort.mp_SigBit)) {
  747.          while (msg = GetMsg(&DBugPort)) {
  748.         DBugDisp    *disp;
  749.  
  750.         //  If console IO message, handle console IO.
  751.         //
  752.  
  753.         for (disp = (DBugDisp *)DisplayList.lh_Head; disp->ds_Node.ln_Succ; disp = (DBugDisp *)disp->ds_Node.ln_Succ) {
  754.             if (msg == (MSG *)&disp->ds_CReadReq) {
  755.             disp->ds_CReadIP = 0;
  756.             CurDisplay = disp;
  757.             HandleConsoleInput(disp, disp->ds_CInChar);
  758.             CurDisplay = disp;
  759.             QueueRead();
  760.             msg = NULL;
  761.             break;
  762.             }
  763.         }
  764.         if (msg == NULL)continue;
  765.  
  766.         //  Not console IO, must be intuition
  767.         //
  768.  
  769.         CurDisplay = NULL;
  770.         for (disp = (DBugDisp *)DisplayList.lh_Head; disp->ds_Node.ln_Succ; disp = (DBugDisp *)disp->ds_Node.ln_Succ) {
  771.             if (((IMSG *)msg)->IDCMPWindow == disp->ds_Win) {
  772.             CurDisplay = disp;
  773.             break;
  774.             }
  775.         }
  776.         if (CurDisplay) {
  777.             switch (((IMSG*)msg)->Class) {
  778.             case IDCMP_CLOSEWINDOW:
  779.             RequestCloseDisplay(CurDisplay,FALSE);
  780.             break;
  781.  
  782.                 case IDCMP_NEWSIZE:
  783.                 GetWindowSize();
  784.                 {
  785.                     WINDOW    *window = CurDisplay->ds_Win;
  786.                     dprefs.left = window->LeftEdge; dprefs.top = window->TopEdge;
  787.                     dprefs.width = window->Width; dprefs.height = window->Height;
  788.                 }
  789.                 ScrClr();
  790.                 setscrollbar(1);    // resize the scroll bar
  791.                 RefreshWindow(-1);
  792.                 ScrStatus("Window Resized");
  793.                 RefreshCommand(1);
  794.                 ScrFlush();
  795.                 break;
  796.  
  797.             case IDCMP_MOUSEBUTTONS:
  798. #if 0
  799. //    multiple windows make ignoring the first click a pain
  800.                 if(ignoreclick) {
  801.                 ignoreclick = 0;
  802.                 break;
  803.                 }
  804. #endif
  805.             {
  806.  
  807. //                    ULONG cseconds,cmicros;
  808.                 USHORT newrow, newcol, nc, nr;
  809.                 switch(((IMSG *)msg)->Code) {
  810.                 case SELECTUP:
  811.                 break;
  812.                 case SELECTDOWN:
  813. //                    CurrentTime(&cseconds,&cmicros); /* what time is it ? */
  814.                     newcol = (((IMSG *)msg)->MouseX);
  815.                     nc = newcol >> 3;
  816.                     newrow = (((IMSG *)msg)->MouseY);
  817.                     nr = newrow >> 3;
  818.                     
  819.                     // check for double click to set breakpoint
  820.                     if((oldcol == nc) && (oldrow == nr)) {
  821.                      // && DoubleClick(seconds,micros,cseconds,cmicros))
  822.                      // people don't like doubleclick timing
  823.                     char *string="bp\r";
  824.                         while (*string) {
  825.                             HandleConsoleInput(disp,*string++);
  826.                     }
  827.                     oldcol = oldrow = 0xFFFF;
  828.                     }
  829.                     else {
  830.                         oldcol = nc;
  831.                         oldrow =  nr;
  832.  
  833.                         //  Process click on data.  Console buffer is empty prefix with
  834.                         //  current command first
  835.  
  836.                         ProcessDataAtCoord(disp, newcol, newrow);
  837.                     }
  838.                     // save times for next time
  839. //                    seconds=cseconds;
  840. //                    micros=cmicros;
  841.                 break;
  842.                 default:;
  843.                 }
  844.                 break;
  845.             }
  846.  
  847.             case IDCMP_REFRESHWINDOW:
  848.                 BeginRefresh(disp->ds_Win);
  849.                 EndRefresh(disp->ds_Win, 1);
  850.                 break;
  851.  
  852.             case IDCMP_INACTIVEWINDOW:
  853.                 InActivateArrows(disp->ds_Win);
  854.                 break;
  855.  
  856.             case IDCMP_ACTIVEWINDOW: {
  857. #if 0
  858.                 ignoreclick = 1;
  859. #endif
  860.                 PageFlag = 0;
  861.                 ActivateArrows(disp->ds_Win);
  862.                 RefreshCommand(1);
  863.                 break;
  864.             }
  865.             
  866.             case IDCMP_INTUITICKS:
  867.                 if(PageFlag) {    // if gadget is held down
  868.                 Ticked = 1;
  869.                 ScrCursoff();
  870.                 if( PageFlag == ID_UP)DoCommand("UP");
  871.                 else DoCommand("DOWN");
  872.                 RefreshPrompt(TRUE);
  873.                 RefreshCommand(1);
  874.                 ScrCurson();
  875.                 }
  876.                 break;
  877.  
  878.             case IDCMP_GADGETUP: {
  879.                 unsigned int id;
  880.                 APTR address = ((IMSG *)msg)->IAddress;
  881.                 if( (id = ((struct Gadget *)address)->GadgetID) != ID_SCROLL) {
  882.                     PageFlag = 0;
  883.                     if(Ticked) {
  884.                     Ticked = 0;
  885.                     break;
  886.                     }
  887.                     ScrCursoff();
  888.                     if( id == ID_UP)DoCommand("UP");
  889.                     else DoCommand("DOWN");
  890.                     RefreshPrompt(TRUE);
  891.                     RefreshCommand(1);
  892.                     ScrCurson();
  893.                 }
  894.                 break;
  895.             }
  896.  
  897.             case IDCMP_MOUSEMOVE:
  898.                 if(++count&1) {
  899.                 break;     // ignore every other mouse
  900.                 }        // else drop through to the scroll bar
  901.  
  902.             case IDCMP_GADGETDOWN: {
  903.                 ULONG current, last;
  904.                 unsigned int id;
  905.                 APTR address = ((IMSG *)msg)->IAddress;
  906.  
  907.                 if( (id = ((struct Gadget *)address)->GadgetID) != ID_SCROLL) {
  908.                 PageFlag = (id == ID_UP) ? ID_UP : ID_DOWN;
  909.                 Ticked = 0;
  910.                 break;
  911.                 }
  912.                 switch (CurDisplay->ds_DisplayMode) {
  913.                 case DISPLAY_DISM:
  914.                 case DISPLAY_SOURCE:
  915.                 case DISPLAY_MIXED:
  916.                 case DISPLAY_BYTES:
  917.                 case DISPLAY_WORDS:
  918.                 case DISPLAY_LONGS:
  919.                     last = (ScrollEnd - ScrollStart) >> 5;
  920.                     break;
  921.  
  922.                 case DISPLAY_HELP:
  923.                     last = HelpSize();
  924.                     break;
  925.  
  926.                 case DISPLAY_SYMBOL:
  927.                     last = SymbolCount;
  928.                     break;
  929.  
  930.                 case DISPLAY_HUNKS:
  931.                         last = numHunks;
  932.                         break;
  933.  
  934.                 case DISPLAY_BREAK:
  935.                     last = MAXBP+5;
  936.                     break;
  937.  
  938.                     default:
  939.                         last = SizeDLIST(&CurDisplay->ds_List);
  940.                 }
  941.                 current = FindScrollerTop(last, CurDisplay->ds_ScrRows, ColorPropInfo.VertPot);
  942.                 // now go do it
  943.                 switch(CurDisplay->ds_DisplayMode) {
  944.                 case DISPLAY_DISM:
  945.                 case DISPLAY_SOURCE:
  946.                 case DISPLAY_MIXED:
  947.                 case DISPLAY_BYTES:
  948.                 case DISPLAY_WORDS:
  949.                 case DISPLAY_LONGS:
  950.                     if((ScrollStart + (current << 5)) != CurDisplay->ds_WindowTop) {
  951.                     CurDisplay->ds_WindowTop = ScrollStart + (current << 5);
  952.                     CurDisplay->ds_WindowTopLine = 0;
  953.                     RefreshWindow(1);
  954.                     }
  955.                     break;
  956.                 case DISPLAY_BREAK:
  957.                     if(topBP != current) {
  958.                     topBP = current;
  959.                     RefreshWindow(1);
  960.                     }
  961.                     break;
  962.                 default:;
  963.                     if(CurDisplay->ds_WindowTop != current) {
  964.                     CurDisplay->ds_WindowTop = current;
  965.                     CurDisplay->ds_WindowTopLine = 0;
  966.                     RefreshWindow(1);
  967.                     }
  968.                 }
  969.                 break;
  970.             }
  971.  
  972.  
  973.             case IDCMP_MENUPICK: {
  974.                 USHORT code = ((IMSG *)msg)->Code;
  975.                 char *string;
  976.  
  977.                 if (!code || (code == MENUNULL))break;
  978.                 while (code && (code != MENUNULL)) { /* handle multiple selection    */
  979.                     item = ItemAddress(DebugMenu,(LONG) code);
  980.                     string = MENU_USERDATA(item);
  981.                     while (*string) {
  982.                         HandleConsoleInput(disp,*string++);
  983.                     }
  984.                     HandleConsoleInput(disp,'\r');
  985.                     code = item->NextSelect;
  986.                 }
  987.                 break;
  988.             }
  989.  
  990.             default:
  991. //                printf("IDCMP Class = %x Code = %x\n", ((IMSG *)msg)->Class, ((IMSG *)msg)->Code);
  992.             break;
  993.             }
  994.         }
  995.         if(msg)ReplyMsg(msg);
  996.         }
  997.     }
  998. //    if (mask & (1<<RexxPort.mp_SigBit)) {
  999.     if (mask & (1<<RexxSigBit)) {
  1000.         ProcessRexxCommands(NULL);
  1001.     }
  1002.     }
  1003. }
  1004.  
  1005. void    HandleConsoleInput(DBugDisp *disp, WORD c) {
  1006.     switch(c) {
  1007.     case -1:
  1008.         break;
  1009.     case 3:
  1010.         RequestCloseDisplay(disp,TRUE);
  1011.         break;
  1012.     case 8:
  1013.         if (commandCol) {
  1014.             UWORD    col;
  1015.  
  1016.             if (commandEnd == commandCol) commandEnd--;
  1017.             commandCol--;
  1018.             for (col=commandCol; col<commandEnd; col++) {
  1019.                 commandLine[col] = commandLine[col+1];
  1020.             }
  1021.             ScrCursoff(); 
  1022.             RefreshCommand(1); 
  1023.             ScrCurson();
  1024.         }
  1025.         break;
  1026.     case 13:
  1027.         commandLine[commandEnd] = '\0';
  1028.         ScrCursoff();
  1029.         commandEnd = 0;     // OPEN command refresh case
  1030.         DoCommand(commandLine);
  1031.         ScrCurson();
  1032.         InitCommand();        // necessary to clear command line
  1033.         ScrCursoff();
  1034.         RefreshCommand(1);
  1035.         ScrCurson();
  1036.         break;
  1037.     case 18:
  1038.         ScrCursoff();
  1039.         RefreshWindow(FALSE);
  1040.         ScrCurson();
  1041.     case 24:
  1042.         InitCommand();
  1043.         ScrCursoff();
  1044.         RefreshCommand(1);
  1045.         ScrCurson();
  1046.         break;
  1047.     case 0x9b:
  1048.         disp->ds_CsiState = 1;
  1049.         break;
  1050.     default:
  1051.         switch (disp->ds_CsiState) {
  1052.         case 0:
  1053.             if (c >= ' ') {
  1054.                 commandLine[commandCol] = c;
  1055.                 if (commandCol == commandEnd) commandEnd++;
  1056.                 commandCol++;
  1057.                 ScrCursoff();
  1058.                 RefreshCommand(1);
  1059.                 ScrCurson();
  1060.             }
  1061.             break;
  1062.         case 1:
  1063.             ScrCursoff();
  1064.  
  1065.             switch (c) {
  1066.             case ' ': disp->ds_CsiState = 3; break;
  1067.             case '0': disp->ds_CsiState = 2; FunctionKey(0); break;
  1068.             case '1': disp->ds_CsiState = 2; FunctionKey(1); break;
  1069.             case '2': disp->ds_CsiState = 2; FunctionKey(2); break;
  1070.             case '3': disp->ds_CsiState = 2; FunctionKey(3); break;
  1071.             case '4': disp->ds_CsiState = 2; FunctionKey(4); break;
  1072.             case '5': disp->ds_CsiState = 2; FunctionKey(5); break;
  1073.             case '6': disp->ds_CsiState = 2; FunctionKey(6); break;
  1074.             case '7': disp->ds_CsiState = 2; FunctionKey(7); break;
  1075.             case '8': disp->ds_CsiState = 2; FunctionKey(8); break;
  1076.             case '9': disp->ds_CsiState = 2; FunctionKey(9); break;
  1077.             case '?': disp->ds_CsiState = 2; HelpKey(); break;
  1078.             case 'A': DoCommand("up"); break;
  1079.             case 'B': DoCommand("down"); break;
  1080.             case 'C': DoCommand("right"); break;
  1081.             case 'D': DoCommand("left"); break;
  1082.             case 'T': DoCommand("pageup"); break;
  1083.             case 'S': DoCommand("pagedown"); break;
  1084.             }
  1085.  
  1086.             if (disp->ds_CsiState == 1) disp->ds_CsiState = 0;
  1087.             RefreshPrompt(TRUE);
  1088.             RefreshCommand(1);
  1089.             ScrCurson();
  1090.             break;
  1091.         case 2:
  1092.             disp->ds_CsiState = 0;
  1093.             break;    // swallow ~
  1094.         case 3:
  1095.             ScrCursoff();
  1096.             switch (c) {
  1097.                 case 'A': DoCommand("shift-left"); break;
  1098.                 case '@': DoCommand("shift-right"); break;
  1099.             }
  1100.             disp->ds_CsiState = 0;
  1101.             ScrCurson();
  1102.             break;
  1103.         }
  1104.     }
  1105. }
  1106.  
  1107. //  We want to close a display, but since we are sharing an IDCMP port
  1108. //  we have to carefully detach it, process all remaining IDCMP messages,
  1109. //  then finally close the window.
  1110. //
  1111. //  Sequence:
  1112. //    (1) modify IDCMP to something that cannot occur to prevent further
  1113. //        incoming messages
  1114. //    (2) detach our custom UserPort (DBugPort)
  1115. //    (3) set UserPort field to NULL
  1116. //    (4) modify IDCMP to 0
  1117.  
  1118. void    RequestCloseDisplay(DBugDisp *disp, int force) {
  1119.     struct DBugDisp *ndisp;
  1120.     int count = 0;
  1121.     struct IntuiText body = {0,1,JAM1,0,5,NULL,"Last DD window.  Really quit ?",NULL};
  1122.     struct IntuiText ok = {0,1,JAM1,0,0,NULL,"OK",NULL};
  1123.     struct IntuiText cancel = {0,1,JAM1,0,0,NULL,"CANCEL",NULL};
  1124.  
  1125.     if (disp && disp->ds_DoneFlag == FALSE) {
  1126.         disp->ds_DoneFlag = TRUE;
  1127.  
  1128.         // ask if really wants to quit if this is last window
  1129.         if(!force) {
  1130.             // scan through displays to see if this is the last window.
  1131.             // if so, bring up a requester
  1132.             for (ndisp = (DBugDisp *)DisplayList.lh_Head; ndisp->ds_Node.ln_Succ; ndisp = (DBugDisp *)ndisp->ds_Node.ln_Succ) {
  1133.                 if (!ndisp->ds_DoneFlag)count++;
  1134.             }
  1135.             if(count == 0) {    // all windows want to close, give warning
  1136.                 if(!AutoRequest(disp->ds_Win,&body,&ok,&cancel,NULL,NULL,300,80)) {
  1137.             disp->ds_DoneFlag = FALSE;    // cancel the quit
  1138.             return;
  1139.             }
  1140.             }
  1141.             }
  1142.  
  1143.         CheckClose = TRUE;
  1144.         if (disp->ds_Win) {
  1145.             Forbid();
  1146.             ModifyIDCMP(disp->ds_Win, IDCMP_REQCLEAR);
  1147.             disp->ds_Win->UserPort = NULL;
  1148.             ModifyIDCMP(disp->ds_Win, 0);
  1149.             Permit();
  1150.         }
  1151.     }
  1152. }
  1153.  
  1154. void    ProcessDataAtCoord(DBugDisp *disp, WORD x, WORD y) {
  1155.     WINDOW *win = disp->ds_Win;
  1156.     WORD row = (y - win->BorderTop) / win->RPort->TxHeight;
  1157.     WORD col = (x - win->BorderLeft) / win->RPort->TxWidth;
  1158.     UBYTE *ptr = &disp->ds_ScrAry[row * disp->ds_ScrCols + col];
  1159.     WORD len;
  1160.     WORD i;
  1161.  
  1162.     if (ValidClipChar[*ptr] == 0) {
  1163.         switch (*ptr) {
  1164.         case '*':
  1165.         case '-':
  1166.         case '/':
  1167.             HandleConsoleInput(disp, *ptr);
  1168.             break;
  1169.         case '<':
  1170.             HandleConsoleInput(disp, 'x'&0x1F);
  1171.             break;
  1172.         case '>':
  1173.             HandleConsoleInput(disp, 13);
  1174.             break;
  1175.         case ' ':
  1176.         case 0:
  1177.             //  mouse to the right of the command line
  1178.             //
  1179.             //  note: comparing row/col in 0+ format to
  1180.             //  screen rows/cols in 1+ format.
  1181.  
  1182.             if (row == disp->ds_ScrRows - 3 && col > disp->ds_PromptLen + 2) {
  1183.                 HandleConsoleInput(disp, 13);
  1184.             }
  1185.             break;
  1186.         }
  1187.         return;
  1188.     }
  1189.     while (col >= 0 && ValidClipChar[*ptr]) {
  1190.         --col;
  1191.         --ptr;
  1192.     }
  1193.     ++col;
  1194.     ++ptr;
  1195.     for (len = 0; ValidClipChar[ptr[len]] && col + len < disp->ds_ScrCols; ++len)
  1196.         ;
  1197.     {
  1198.         char *jp;
  1199.         int nflag = 0;
  1200.  
  1201.         if(*ptr == '-')nflag = 1;
  1202.         if (ptr[nflag] == '$' || (len == 8 && (strtol(ptr, &jp, 16), (jp - ptr == 8)))) {
  1203.                 if(nflag) {
  1204.                 HandleConsoleInput(disp, '-');
  1205.                 ++ptr;
  1206.                 --len;
  1207.             }
  1208.  
  1209.             HandleConsoleInput(disp, '0');
  1210.             HandleConsoleInput(disp, 'x');
  1211.             ++ptr;
  1212.             --len;
  1213.         }
  1214.     }
  1215.     if (len == 2 && ptr[0] == '+' && ptr[1] == '+')--len;
  1216.  
  1217.     // handle those silly function keys
  1218.  
  1219.     if (len == 1 && ptr[0] >= '1' && ptr[0] <= '9' && ptr[1] == ':') {
  1220.         FunctionKey(ptr[0] - '1');
  1221.         return;
  1222.     }
  1223.     // and F10
  1224.     if(len == 2 && ptr[0] == '1' && ptr[1] == '0' && ptr[2] == ':') {
  1225.         FunctionKey(9);
  1226.         return;
  1227.     }
  1228.  
  1229.     for (i = 0; i < len; ++i)HandleConsoleInput(disp, ptr[i]);
  1230.  
  1231.     if((len == 2) && (ptr[2] == ':')) {    // treat it as a register clip
  1232.             HandleConsoleInput(disp, ':');
  1233.     }
  1234.  
  1235.     for(i=0; i<= 9; i++) {
  1236.         if(!strncmp(ptr,fkeys[i],len)) {
  1237.         HandleConsoleInput(disp, '\r');
  1238.         return;
  1239.         }
  1240.     }
  1241.     HandleConsoleInput(disp, ' ');
  1242. }
  1243.  
  1244. char    *ModeNames[10] = {
  1245.     "DISM MODE",
  1246.     "SOURCE MODE",
  1247.     "MIXED MODE",
  1248.     "BYTES (HEX)",
  1249.     "WORDS (HEX)",
  1250.     "LONGS (HEX)",
  1251.     "HUNKS",
  1252.     "SYMBOLS",
  1253.     "ONLINE HELP",
  1254.     "BREAKPOINTS"
  1255. };
  1256.  
  1257. /* The screen title is used to contain the debugger name and version,
  1258.  * its arexx port name, the current display mode, and
  1259.  * the program under debug with its arguments
  1260.  */
  1261.  
  1262. void SetTitle(char *title, DBugDisp *disp)
  1263. {
  1264.     int type;
  1265.     DBugDisp *ldisp = disp;
  1266.  
  1267.     if(!ldisp)ldisp=CurDisplay;
  1268.     type = ldisp->ds_DisplayMode;
  1269.  
  1270.     strcpy(ldisp->ds_windowTitle, " (" VERS " PORT: ");
  1271.     strcat(ldisp->ds_windowTitle,rexxhostname);
  1272.     strcat(ldisp->ds_windowTitle,") ");
  1273.  
  1274.     if((type < 10) && !title) {
  1275.     strcat(ldisp->ds_windowTitle,ModeNames[type]);
  1276.     }
  1277.     else {
  1278.     strcat(ldisp->ds_windowTitle,title);
  1279.     }
  1280.     strcat(ldisp->ds_windowTitle," ");
  1281.  
  1282.     strcat(ldisp->ds_windowTitle, targetName);
  1283.     if(argSize > 1)strncat(ldisp->ds_windowTitle, args, argSize-1);
  1284.     SetWindowTitles(ldisp->ds_Win,ldisp->ds_windowTitle,NULL);
  1285. }
  1286.  
  1287. void draw_fkey_boxes(void)
  1288. {
  1289. int i,xcol = 2,yrow = CurDisplay->ds_ScrRows, xlen;
  1290.  
  1291.     for(i=0; i < 10; i++) {
  1292.     xlen = strlen(fkeys[i]) + ((i == 9) ? 3 : 2);
  1293.     drawbox(xcol,yrow,xlen, -1);
  1294.     xcol += (xlen+1);
  1295.     }
  1296. }
  1297.  
  1298. // given the column, row, length, and height, draw a box
  1299.  
  1300. void drawbox(int xcol,int yrow, int xcollen, int yrowlen)
  1301. {
  1302.     WINDOW     *win;
  1303.     RPORT     *rp;
  1304.     int x,y,xlen,ylen, xmax, ymax;
  1305.  
  1306.     if(win = CurDisplay->ds_Win) {
  1307.     rp = win->RPort;
  1308.  
  1309.         y = win->BorderTop + ((yrow)  * rp->TxHeight);
  1310.     x = xcol * rp->TxWidth - 4;
  1311.     xlen = xcollen * rp->TxWidth + 1;
  1312.     ylen = rp->TxHeight + 3;
  1313.     
  1314.     if(x > (xmax = CurDisplay->ds_ScrCols * rp->TxWidth - 1))return; // out of range
  1315.     xlen = (x+xlen) <= xmax ? xlen : xmax-x;
  1316.  
  1317.     SetAPen(rp,2);    // white
  1318.     Move(rp,x,y);
  1319.     Draw(rp,x,y-ylen);
  1320.     Draw(rp,x+xlen,y-ylen);
  1321.  
  1322.     SetAPen(rp,1);    // black
  1323.     Draw(rp,x+xlen,y);
  1324.     if(y > (ymax = win->Height - 3))return; // out of range
  1325.     Draw(rp,x,y);
  1326.     }
  1327. }
  1328.  
  1329.  
  1330.  
  1331. void drawdoublebox(void)
  1332. {
  1333.     WINDOW     *win;
  1334.     RPORT     *rp;
  1335.     int x, y, xlen, ylen, i, j;
  1336.  
  1337.     if(win = CurDisplay->ds_Win) {
  1338.     rp = win->RPort;
  1339.     x = win->BorderLeft; // + rp->TxWidth - 6;
  1340.         y = win->BorderTop + (CurDisplay->ds_ScrRows-2) * rp->TxHeight + 2;
  1341. //    xlen = (CurDisplay->ds_ScrCols) * rp->TxWidth; // + 4;
  1342.     xlen = win->Width - win->BorderRight - win->BorderLeft - 2;
  1343.     ylen = rp->TxHeight + 6;
  1344.  
  1345.     for(i=2, j=0; i>0; i--, j++) {
  1346.         SetAPen(rp,i);
  1347. //        Move(rp,x+j,y+j);
  1348. //        Draw(rp,x+j,y-ylen+j);
  1349.         Move(rp,x+j,y-ylen+j);
  1350.         Draw(rp,x+xlen+j,y-ylen+j);
  1351. //        Draw(rp,x+xlen+j,y+j);
  1352.         Move(rp,x+xlen+j,y+j);
  1353.         Draw(rp,x+j,y+j);
  1354.     }
  1355.     }
  1356. }
  1357.